package com.rpc.example.protocol;

import com.rpc.example.IRegitserService;
import com.rpc.example.ServiceInfo;
import com.rpc.example.core.Protocol;
import com.rpc.example.core.Request;
import com.rpc.example.handler.RpcClientInitialHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Elvis
 * @version 1.0, 2022/11/11
 */
@Slf4j
public class NettyClient {
    // private String hostName;
    // private int port;
    private Bootstrap bootstrap;

    private NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();

    public NettyClient() {

        bootstrap = new Bootstrap();
    }

    public void sendRequest(Protocol<Request> protocol , IRegitserService registerService) {
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .handler(new RpcClientInitialHandler());

        try {
            // ServiceInfo discovery = registerService.discovery(protocol.getData().getClassName());
            ServiceInfo discovery = registerService.discovery(protocol.getData().getApplicationName());
            ChannelFuture sync = bootstrap.connect(discovery.getServiceAddress(), discovery.getServicePort()).sync();
            sync.addListener((ChannelFutureListener) channelFuture -> {
                if (channelFuture.isSuccess()) {
                    log.info("+++++++++++连接服务端成功: {} {}", discovery.getServiceAddress(), discovery.getServicePort());
                } else {
                    log.info("+++++++++++连接服务端异常++++++++++");
                    channelFuture.cause().printStackTrace();
                    eventLoopGroup.shutdownGracefully();
                }
            });
            log.info("###########开始发送数据#######");
            log.info("#############################");
            sync.channel().writeAndFlush(protocol);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
